package com.kaikai.vod.service.impl;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.DeleteVideoRequest;

import com.kaikai.commonutils.JsonUtil;
import com.kaikai.servicebase.exceptionhandler.MyException;

import com.kaikai.vod.service.VodService;
import com.kaikai.vod.util.AliyunVodSDKUtils;
import com.kaikai.vod.util.ConstantPropertiesUtil;

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程视频 服务实现类
 * </p>
 *
 * @author yujiankai
 * @since 2021-07-20
 */
@Service
public class VodServiceImpl implements VodService {

    @Override
    public String uploadVideo(MultipartFile multipartFile) {
        File file = null;
        try {
            InputStream inputStream = multipartFile.getInputStream();
            String originalFilename = multipartFile.getOriginalFilename();
            //文件名
            String title = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            // 获取文件后缀
            String prefix = originalFilename.substring(originalFilename.lastIndexOf("."));
            //生成临时文件
            file = File.createTempFile(originalFilename + RandomUtils.nextInt(), prefix);
            multipartFile.transferTo(file);
            String videoSize = ReadVideoSize(file);
            String videoDuration = ReadVideoTime(file);
            UploadStreamRequest request = new UploadStreamRequest(
                    ConstantPropertiesUtil.ACCESS_KEY_ID,
                    ConstantPropertiesUtil.ACCESS_KEY_SECRET,
                    title, originalFilename, inputStream);

            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);

            //如果设置回调URL无效，不影响视频上传，可以返回VideoId同时会返回错误码。
            // 其他情况上传失败时，VideoId为空，此时需要根据返回错误码分析具体错误原因
            String videoId = response.getVideoId();
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("videoId", videoId);
            resultMap.put("videoSize", videoSize);
            resultMap.put("videoDuration", videoDuration);
            if (!response.isSuccess()) {
                String errorMessage = "阿里云上传错误：" + "code：" + response.getCode() + ", message：" + response.getMessage();
                if (StringUtils.isEmpty(videoId)) {
                    throw new MyException(20001, errorMessage);
                }
            }
            return JsonUtil.convertMapToJson(resultMap);
        } catch (IOException e) {
            e.printStackTrace();
            throw new MyException(20001, "vod 服务上传失败");
        } finally {
            if (file != null) {
                //清除临时文件
                file.deleteOnExit();
            }
        }
    }

    /**
     * @param source
     * @return java.lang.String
     * @Author yujiankai
     * @Description 获取视频大小
     * @date 2022/2/22 10:53
     */
    private static String ReadVideoSize(File source) {
        FileChannel fc = null;
        String size = "";
        try {
            @SuppressWarnings("resource")
            FileInputStream fis = new FileInputStream(source);
            fc = fis.getChannel();
            BigDecimal fileSize = new BigDecimal(fc.size());
            size = fileSize.divide(new BigDecimal(1048576), 2, RoundingMode.HALF_UP) + "MB";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != fc) {
                try {
                    fc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return size;
    }

    private static String ReadVideoTime(File source) {
        Encoder encoder = new Encoder();
        String length = "";
        try {
            MultimediaInfo m = encoder.getInfo(source);
            long ls = m.getDuration() / 1000;
            int hour = (int) (ls / 3600);
            int minute = (int) (ls % 3600) / 60;
            int second = (int) (ls - hour * 3600 - minute * 60);
            length = hour + "'" + minute + "''" + second + "'''";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return length;
    }

    //根据视频id删除视频
    @Override
    public void removeVideoById(String videoId) {

        try {
            //初始化对象
            DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                    ConstantPropertiesUtil.ACCESS_KEY_ID,
                    ConstantPropertiesUtil.ACCESS_KEY_SECRET);
            //创建删除视频request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //向request中设置id
            request.setVideoIds(videoId);
            //调用初始化对象进行删除
            client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
            throw new MyException(20001, "视频删除失败");
        }
    }

    @Override
    public void removeVideoByIds(List videoList) {
        try {
            //初始化对象
            DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                    ConstantPropertiesUtil.ACCESS_KEY_ID,
                    ConstantPropertiesUtil.ACCESS_KEY_SECRET);
            //创建删除视频request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //向request中设置id  将字符串以逗号分割
            String videoIds = org.apache.commons.lang.StringUtils.join(videoList.toArray(), ",");
            request.setVideoIds(videoIds);
            //调用初始化对象进行删除
            client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
            throw new MyException(20001, "视频删除失败");
        }
    }


}
